package com.university.evaluation.common;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.university.evaluation.enums.RespEnum;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
 * 统一API响应结果封装类
 * <p>
 * 标准化接口返回格式，包含状态码(code)、消息提示(msg)和业务数据(data)
 * 提供静态工厂方法快速创建成功/失败响应，支持链式调用风格
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)  // 序列化时忽略null值字段
public class ResponseResult<T> implements Serializable {

    private static final long serialVersionUID = 1L;

    /** 响应状态码（参考RespEnum定义） */
    private Integer code;

    /** 响应消息提示 */
    private String msg;

    /** 响应业务数据 */
    private T data;


    // =================== 成功响应 - 静态工厂方法 ===================

    /**
     * 构建无数据的成功响应
     */
    public static <T> ResponseResult<T> success() {
        return new ResponseResult<>(
                RespEnum.SUCCESS.getCode(),
                RespEnum.SUCCESS.getMsg(),
                null
        );
    }

    /**
     * 构建带业务数据的成功响应
     * @param data 业务数据对象
     */
    public static <T> ResponseResult<T> success(T data) {
        return new ResponseResult<>(
                RespEnum.SUCCESS.getCode(),
                RespEnum.SUCCESS.getMsg(),
                data
        );
    }

    /**
     * 构建自定义消息的成功响应（无数据）
     * @param msg 自定义成功消息
     */
    public static <T> ResponseResult<T> success(String msg) {
        return new ResponseResult<>(
                RespEnum.SUCCESS.getCode(),
                msg,
                null
        );
    }

    /**
     * 构建自定义消息+业务数据的成功响应
     * @param msg 自定义成功消息
     * @param data 业务数据对象
     */
    public static <T> ResponseResult<T> success(String msg, T data) {
        return new ResponseResult<>(
                RespEnum.SUCCESS.getCode(),
                msg,
                data
        );
    }


    // =================== 失败响应 - 静态工厂方法 ===================

    /**
     * 构建默认的失败响应（无数据）
     */
    public static <T> ResponseResult<T> failure() {
        return new ResponseResult<>(
                RespEnum.FAILURE.getCode(),
                RespEnum.FAILURE.getMsg(),
                null
        );
    }

    /**
     * 构建自定义消息的失败响应（无数据）
     * @param msg 自定义失败消息
     */
    public static <T> ResponseResult<T> failure(String msg) {
        return new ResponseResult<>(
                RespEnum.FAILURE.getCode(),
                msg,
                null
        );
    }

    /**
     * 构建自定义状态码+消息的失败响应（无数据）
     * @param code 自定义错误码
     * @param msg 自定义失败消息
     */
    public static <T> ResponseResult<T> failure(Integer code, String msg) {
        return new ResponseResult<>(code, msg, null);
    }

    /**
     * 根据响应枚举构建失败响应（无数据）
     * @param respEnum 响应枚举（包含预设的code和msg）
     */
    public static <T> ResponseResult<T> failure(RespEnum respEnum) {
        return new ResponseResult<>(
                respEnum.getCode(),
                respEnum.getMsg(),
                null
        );
    }

    /**
     * 根据响应枚举构建带数据的失败响应
     * @param respEnum 响应枚举（包含预设的code和msg）
     * @param data 附加的业务数据（如错误详情）
     */
    public static <T> ResponseResult<T> failure(RespEnum respEnum, T data) {
        return new ResponseResult<>(
                respEnum.getCode(),
                respEnum.getMsg(),
                data
        );
    }


    // =================== 实例方法 - 状态判断 ===================

    /**
     * 判断响应是否为成功状态
     * @return true=成功，false=失败
     */
    @JsonIgnore  // 避免被JSON序列化
    public boolean isSuccess() {
        return this.code != null && this.code.equals(RespEnum.SUCCESS.getCode());
    }

    /**
     * 判断响应是否为失败状态
     * @return true=失败，false=成功
     */
    @JsonIgnore  // 避免被JSON序列化
    public boolean isFailure() {
        return !isSuccess();
    }
}
